from django.utils.translation import gettext_lazy as _
from django.utils.text import slugify


class BaseSettingsWrapper:
    _instance = None

    def __init__(self, title=None):
        self.title = _('Settings') if title is None else title
        self._tab_list = list()

    def register(self, tab):
        self._tab_list.append(tab)

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            return super().__new__(cls)
        raise TypeError(f"Can't create instance directly of {cls!r}")

    @classmethod
    def get_instance(cls):
        if cls._instance is None:
            cls._instance = cls()

        return cls._instance

    def tabs(self):
        # Weard django template issue, tabs (self._tab_list) couldn't be passed to the template?!
        return {tab.name: tab.form_instance(refresh=True) for tab in self._tab_list}

    def forms_class(self):
        return (tab.form_class() for tab in self._tab_list)

    def handle_save(self, req):
        from .utils import all_settings, SettingsManager

        settings = all_settings()

        for tab in self._tab_list:
            # TODO: tab.name should be slugified
            if req.POST.get('section') == slugify(tab.name):
                form = tab.create_form_instance(
                    req.POST, req.FILES, initial=settings)

                if form.is_valid():
                    SettingsManager.update(form.cleaned_data)
                    return True
                else:
                    return False
            else:
                # Update the form with new initials
                tab.create_form_instance(initial=settings)


SettingsWrapper = BaseSettingsWrapper.get_instance()


class Tab:
    def __init__(self, name=None, enctype=None, support_files=False):
        self.name = name
        self.enctype = (
            'multipart/form-data' if support_files else None) if enctype is None else enctype
        self._form_instance = None

    def __call__(self, form):
        self._form = form
        # Passing enctype to the form instance.
        self._form.enctype = self.form_enctype()
        # register the Tab
        SettingsWrapper.register(self)
        return self._form

    def form_instance(self, refresh=False):
        from .utils import all_settings

        if refresh or self._form_instance is None:
            self.create_form_instance(initial=all_settings())
        return self._form_instance

    def create_form_instance(self, *args, **kwargs):
        self._form_instance = self._form(*args, **kwargs)
        return self._form_instance

    def form_class(self):
        return self._form

    def form_enctype(self):
        if self.enctype is None:
            return ""
        return f"enctype={self.enctype}"

    def __repr__(self):
        return f"<Tab (name='{self.name}')>"

    def __str__(self):
        return self.name
